<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>去中心化投票系统</title>
    <script src="https://cdn.jsdelivr.net/npm/web3@1.8.0/dist/web3.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
            text-align: center;
        }
        .section {
            margin-bottom: 30px;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .section h2 {
            margin-top: 0;
            color: #444;
        }
        button {
            background-color: #4CAF50;
            color: white;
            border: none;
            padding: 10px 15px;
            border-radius: 4px;
            cursor: pointer;
            margin: 5px 0;
        }
        button:hover {
            background-color: #45a049;
        }
        button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }
        input, textarea, select {
            width: 100%;
            padding: 8px;
            margin: 5px 0 15px;
            display: inline-block;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-sizing: border-box;
        }
        .status {
            padding: 10px;
            background-color: #e7f3fe;
            border-left: 6px solid #2196F3;
            margin-bottom: 20px;
        }
        .proposal {
            border: 1px solid #ddd;
            padding: 15px;
            margin-bottom: 15px;
            border-radius: 5px;
        }
        .proposal h3 {
            margin-top: 0;
        }
        .wallet-info {
            background-color: #f8f9fa;
            padding: 10px;
            border-radius: 4px;
            margin-bottom: 20px;
        }
        .error {
            color: red;
            margin: 5px 0;
        }
        #registerForm {
            margin: 15px 0;
            padding: 15px;
            background-color: #f8f9fa;
            border-radius: 5px;
        }
        #registerForm input {
            width: 100%;
            padding: 8px;
            margin: 8px 0;
        }
        #registerStatus {
            margin-top: 10px;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>去中心化投票系统</h1>
        
        <div class="wallet-info">
            <button id="connectWallet">连接MetaMask钱包</button>
            <div id="walletAddress"></div>
            <div id="networkInfo"></div>
            <div id="contractInfo">
                <h3>合约设置</h3>
                <input type="text" id="contractAddress" placeholder="输入合约地址">
                <textarea id="contractABI" placeholder="输入合约ABI"></textarea>
                <button id="loadContract">加载合约</button>
            </div>
        </div>
        
        <div class="status">
            <h2>当前状态</h2>
            <div id="currentStatus"></div>
            <div id="votingInfo"></div>
        </div>
        
        <div class="section" id="adminSection">
            <h2>管理员功能</h2>
            <div id="adminFunctions"></div>
        </div>
        
        <div class="section" id="voterRegistrationSection">
            <h2>选民注册</h2>
            <div id="voterRegistration">
                <div id="registerForm">
                    <h3>注册为选民</h3>
                    <p>请输入你的钱包地址进行注册：</p>
                    <input type="text" id="voterAddress" placeholder="0x...">
                    <button onclick="registerAsVoter()">提交注册</button>
                    <p id="registerStatus"></p>
                </div>
                <div id="voterStatusMessage">
                    <p>请联系管理员注册为选民</p>
                </div>
            </div>
        </div>
        
        <div class="section" id="proposalSection">
            <h2>提案管理</h2>
            <div id="proposalManagement"></div>
            <div id="proposalsList"></div>
        </div>
        
        <div class="section" id="votingSection">
            <h2>投票</h2>
            <div id="votingFunctions"></div>
        </div>
    </div>

    <script>
        // 全局变量
        let web3;
        let contract;
        let accounts = [];
        let currentUserIsOwner = false;
        let currentUserIsRegistered = false;
        let currentStatus = "";
        let proposals = [];
        
        // DOM元素
        const connectWalletBtn = document.getElementById('connectWallet');
        const walletAddressDiv = document.getElementById('walletAddress');
        const networkInfoDiv = document.getElementById('networkInfo');
        const currentStatusDiv = document.getElementById('currentStatus');
        const votingInfoDiv = document.getElementById('votingInfo');
        const adminFunctionsDiv = document.getElementById('adminFunctions');
        const voterRegistrationDiv = document.getElementById('voterRegistration');
        const proposalManagementDiv = document.getElementById('proposalManagement');
        const proposalsListDiv = document.getElementById('proposalsList');
        const votingFunctionsDiv = document.getElementById('votingFunctions');
        const loadContractBtn = document.getElementById('loadContract');
        const registerForm = document.getElementById('registerForm');
        const voterStatusMessage = document.getElementById('voterStatusMessage');
        
        // 初始化
        window.addEventListener('load', async () => {
            // 检查是否安装了MetaMask
            if (window.ethereum) {
                web3 = new Web3(window.ethereum);
                try {
                    // 请求账户访问
                    accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
                    updateWalletInfo();
                    
                    // 监听账户变化
                    window.ethereum.on('accountsChanged', (newAccounts) => {
                        accounts = newAccounts;
                        updateWalletInfo();
                        loadContractData();
                    });
                    
                    // 监听网络变化
                    window.ethereum.on('chainChanged', () => {
                        window.location.reload();
                    });
                } catch (error) {
                    console.error("用户拒绝访问账户:", error);
                }
            } else {
                alert('请安装MetaMask扩展程序以使用此应用');
            }
            
            connectWalletBtn.addEventListener('click', connectWallet);
            loadContractBtn.addEventListener('click', loadContract);
        });
        
        // 连接钱包
        async function connectWallet() {
            if (window.ethereum) {
                try {
                    accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
                    updateWalletInfo();
                } catch (error) {
                    console.error("用户拒绝访问账户:", error);
                }
            } else {
                alert('请安装MetaMask扩展程序以使用此应用');
            }
        }
        
        // 更新钱包信息
        function updateWalletInfo() {
            if (accounts.length > 0) {
                walletAddressDiv.textContent = `当前账户: ${accounts[0]}`;
                connectWalletBtn.textContent = "切换账户";
                
                // 获取网络信息
                web3.eth.net.getId().then(netId => {
                    let networkName;
                    switch(netId) {
                        case 1: networkName = "以太坊主网"; break;
                        case 5: networkName = "Goerli测试网"; break;
                        case 11155111: networkName = "Sepolia测试网"; break;
                        case 137: networkName = "Polygon主网"; break;
                        case 80001: networkName = "Mumbai测试网"; break;
                        default: networkName = `未知网络 (ID: ${netId})`;
                    }
                    networkInfoDiv.textContent = `网络: ${networkName}`;
                });
            } else {
                walletAddressDiv.textContent = "未连接钱包";
            }
        }
        
        // 加载合约
        async function loadContract() {
            const contractAddress = document.getElementById('contractAddress').value;
            const contractABI = document.getElementById('contractABI').value;
            
            if (!contractAddress || !contractABI) {
                alert("请输入合约地址和ABI");
                return;
            }
            
            try {
                const abi = JSON.parse(contractABI);
                contract = new web3.eth.Contract(abi, contractAddress);
                await loadContractData();
            } catch (error) {
                console.error("加载合约失败:", error);
                alert("合约加载失败，请检查地址和ABI是否正确");
            }
        }
        
        // 加载合约数据
        async function loadContractData() {
            if (!contract || !accounts.length) return;
            
            try {
                // 检查当前用户是否是所有者
                const owner = await contract.methods.owner().call();
                currentUserIsOwner = (owner.toLowerCase() === accounts[0].toLowerCase());
                
                // 检查当前用户是否是已注册选民
                const voterInfo = await contract.methods.getVoterInfo(accounts[0]).call();
                currentUserIsRegistered = voterInfo.isRegistered;
                
                // 更新选民注册界面显示
                if (currentUserIsRegistered) {
                    registerForm.style.display = 'none';
                    voterStatusMessage.innerHTML = '<p>你已经是注册选民</p>';
                } else {
                    registerForm.style.display = 'block';
                    voterStatusMessage.innerHTML = '<p>请联系管理员注册为选民</p>';
                }
                
                // 获取当前状态
                const status = await contract.methods.currentStatus().call();
                currentStatus = getStatusName(status);
                currentStatusDiv.textContent = `当前状态: ${currentStatus}`;
                
                // 获取投票信息
                const votingDuration = await contract.methods.votingDuration().call();
                const voterCount = await contract.methods.getVoterCount().call();
                const proposalCount = await contract.methods.proposalCount().call();
                
                votingInfoDiv.innerHTML = `
                    <p>投票持续时间: ${votingDuration} 秒</p>
                    <p>已注册选民: ${voterCount}</p>
                    <p>提案数量: ${proposalCount}</p>
                `;
                
                // 更新UI
                updateAdminUI();
                updateProposalUI();
                updateVotingUI();
                
                // 加载提案列表
                await loadProposals();
            } catch (error) {
                console.error("加载合约数据失败:", error);
            }
        }
        
        // 选民注册函数
        async function registerAsVoter() {
            const address = document.getElementById('voterAddress').value;
            const statusElement = document.getElementById('registerStatus');
            
            if(!web3.utils.isAddress(address)) {
                statusElement.textContent = "错误：请输入有效的以太坊地址";
                statusElement.style.color = "red";
                return;
            }
            
            try {
                statusElement.textContent = "正在提交注册请求...";
                statusElement.style.color = "blue";
                
                // 调用合约的registerVoter函数
                await contract.methods.registerVoter(address)
                    .send({ from: accounts[0], gas: 300000 });
                    
                statusElement.textContent = "注册成功！";
                statusElement.style.color = "green";
                
                // 刷新页面状态
                setTimeout(() => {
                    window.location.reload();
                }, 2000);
                
            } catch (error) {
                console.error("注册失败:", error);
                statusElement.textContent = `注册失败: ${error.message}`;
                statusElement.style.color = "red";
            }
        }
        
        // 获取状态名称
        function getStatusName(status) {
            const statuses = ["Created", "Started", "Voting", "Ended", "Cancelled"];
            return statuses[parseInt(status)] || "Unknown";
        }
        
        // 更新管理员UI
        function updateAdminUI() {
            adminFunctionsDiv.innerHTML = "";
            
            if (!currentUserIsOwner) {
                adminFunctionsDiv.innerHTML = "<p>你不是合约所有者</p>";
                return;
            }
            
            let html = "";
            
            if (currentStatus === "Created") {
                html += `
                    <button onclick="startProposalPhase()">开始提案阶段</button>
                    <div>
                        <h3>注册选民</h3>
                        <input type="text" id="adminVoterAddress" placeholder="输入选民地址">
                        <button onclick="adminRegisterVoter()">注册单个选民</button>
                        <button onclick="batchRegisterVoters()">批量注册选民</button>
                        <textarea id="batchVoters" placeholder="输入多个地址，每行一个"></textarea>
                    </div>
                `;
            }
            
            if (currentStatus === "Started") {
                html += `<button onclick="startVoting()">开始投票</button>`;
            }
            
            if (currentStatus === "Voting") {
                html += `<button onclick="endVoting()">结束投票</button>`;
            }
            
            if (currentStatus === "Ended") {
                html += `
                    <button onclick="executeProposal()">执行获胜提案</button>
                    <div id="winningProposalInfo"></div>
                `;
                loadWinningProposal();
            }
            
            if (currentStatus !== "Ended" && currentStatus !== "Cancelled") {
                html += `<button onclick="cancelVoting()">取消投票</button>`;
            }
            
            adminFunctionsDiv.innerHTML = html;
        }
        
        // 更新提案UI
        function updateProposalUI() {
            proposalManagementDiv.innerHTML = "";
            
            if (!currentUserIsRegistered) {
                proposalManagementDiv.innerHTML = "<p>你需要是注册选民才能创建提案</p>";
                return;
            }
            
            if (currentStatus === "Started") {
                proposalManagementDiv.innerHTML = `
                    <div>
                        <h3>创建新提案</h3>
                        <input type="text" id="proposalTitle" placeholder="提案标题">
                        <textarea id="proposalDescription" placeholder="提案描述"></textarea>
                        <button onclick="addProposal()">提交提案</button>
                    </div>
                `;
            } else {
                proposalManagementDiv.innerHTML = "<p>当前阶段不能创建提案</p>";
            }
        }
        
        // 更新投票UI
        function updateVotingUI() {
            votingFunctionsDiv.innerHTML = "";
            
            if (!currentUserIsRegistered) {
                votingFunctionsDiv.innerHTML = "<p>你需要是注册选民才能投票</p>";
                return;
            }
            
            if (currentStatus === "Voting") {
                votingFunctionsDiv.innerHTML = `
                    <p>请从下面的提案列表中选择一个进行投票</p>
                    <div id="voteOptions"></div>
                `;
            } else {
                votingFunctionsDiv.innerHTML = `<p>当前阶段不能投票</p>`;
            }
        }
        
        // 加载提案列表
        async function loadProposals() {
            proposalsListDiv.innerHTML = "<h3>提案列表</h3>";
            
            try {
                const proposalIds = await contract.methods.getAllProposals().call();
                
                if (proposalIds.length === 0) {
                    proposalsListDiv.innerHTML += "<p>暂无提案</p>";
                    return;
                }
                
                proposals = [];
                for (const id of proposalIds) {
                    const proposal = await contract.methods.getProposal(id).call();
                    proposals.push({
                        id: id,
                        title: proposal.title,
                        description: proposal.description,
                        proposer: proposal.proposer,
                        voteCount: proposal.voteCount,
                        startTime: proposal.startTime,
                        endTime: proposal.endTime,
                        isExecuted: proposal.isExecuted
                    });
                    
                    const isVoting = currentStatus === "Voting";
                    const canVote = isVoting && currentUserIsRegistered;
                    
                    let voteButton = "";
                    if (canVote) {
                        voteButton = `<button onclick="castVote(${id})">投票</button>`;
                    }
                    
                    proposalsListDiv.innerHTML += `
                        <div class="proposal">
                            <h3>${proposal.title} (ID: ${id})</h3>
                            <p>${proposal.description}</p>
                            <p>提案人: ${proposal.proposer}</p>
                            <p>票数: ${proposal.voteCount}</p>
                            <p>状态: ${proposal.isExecuted ? "已执行" : "未执行"}</p>
                            ${voteButton}
                        </div>
                    `;
                }
            } catch (error) {
                console.error("加载提案失败:", error);
                proposalsListDiv.innerHTML += "<p>加载提案失败</p>";
            }
        }
        
        // 加载获胜提案
        async function loadWinningProposal() {
            try {
                const winningProposalDiv = document.getElementById('winningProposalInfo');
                if (!winningProposalDiv) return;
                
                const hasWinningProposal = await contract.methods.hasWinningProposal().call();
                if (hasWinningProposal) {
                    const [winningId, voteCount] = await contract.methods.getWinningProposal().call();
                    winningProposalDiv.innerHTML = `
                        <p>获胜提案ID: ${winningId}</p>
                        <p>获得票数: ${voteCount}</p>
                    `;
                } else {
                    winningProposalDiv.innerHTML = "<p>没有获胜提案或出现平局</p>";
                }
            } catch (error) {
                console.error("加载获胜提案失败:", error);
            }
        }
        
        // 管理员注册选民
        async function adminRegisterVoter() {
            const voterAddress = document.getElementById('adminVoterAddress').value;
            if (!voterAddress) {
                alert("请输入选民地址");
                return;
            }
            
            try {
                await contract.methods.registerVoter(voterAddress).send({ from: accounts[0], gas: 300000 });
                alert("选民注册成功");
                await loadContractData();
            } catch (error) {
                console.error("注册选民失败:", error);
                alert(`注册选民失败: ${error.message}`);
            }
        }
        
        // 批量注册选民
        async function batchRegisterVoters() {
            const batchInput = document.getElementById('batchVoters').value;
            if (!batchInput) {
                alert("请输入选民地址列表");
                return;
            }
            
            const addresses = batchInput.split('\n').filter(addr => addr.trim() !== "");
            if (addresses.length === 0) {
                alert("没有有效的地址");
                return;
            }
            
            try {
                await contract.methods.batchRegisterVoters(addresses).send({ from: accounts[0], gas: 300000 * addresses.length });
                alert(`成功批量注册 ${addresses.length} 个选民`);
                await loadContractData();
            } catch (error) {
                console.error("批量注册选民失败:", error);
                alert(`批量注册选民失败: ${error.message}`);
            }
        }
        
        // 开始提案阶段
        async function startProposalPhase() {
            try {
                await contract.methods.startProposalPhase().send({ from: accounts[0], gas: 300000 });
                alert("提案阶段已开始");
                await loadContractData();
            } catch (error) {
                console.error("开始提案阶段失败:", error);
                alert(`开始提案阶段失败: ${error.message}`);
            }
        }
        
        // 添加提案
        async function addProposal() {
            const title = document.getElementById('proposalTitle').value;
            const description = document.getElementById('proposalDescription').value;
            
            if (!title || !description) {
                alert("请输入提案标题和描述");
                return;
            }
            
            try {
                await contract.methods.addProposal(title, description).send({ from: accounts[0], gas: 300000 });
                alert("提案提交成功");
                await loadProposals();
            } catch (error) {
                console.error("提交提案失败:", error);
                alert(`提交提案失败: ${error.message}`);
            }
        }
        
        // 开始投票
        async function startVoting() {
            try {
                await contract.methods.startVoting().send({ from: accounts[0], gas: 300000 });
                alert("投票已开始");
                await loadContractData();
            } catch (error) {
                console.error("开始投票失败:", error);
                alert(`开始投票失败: ${error.message}`);
            }
        }
        
        // 投票
        async function castVote(proposalId) {
            try {
                await contract.methods.castVote(proposalId).send({ from: accounts[0], gas: 300000 });
                alert("投票成功");
                await loadContractData();
            } catch (error) {
                console.error("投票失败:", error);
                alert(`投票失败: ${error.message}`);
            }
        }
        
        // 结束投票
        async function endVoting() {
            try {
                await contract.methods.endVoting().send({ from: accounts[0], gas: 300000 });
                alert("投票已结束");
                await loadContractData();
            } catch (error) {
                console.error("结束投票失败:", error);
                alert(`结束投票失败: ${error.message}`);
            }
        }
        
        // 执行提案
        async function executeProposal() {
            try {
                const winningProposalId = await contract.methods.winningProposalId().call();
                await contract.methods.executeProposal(winningProposalId).send({ from: accounts[0], gas: 300000 });
                alert("提案执行成功");
                await loadContractData();
            } catch (error) {
                console.error("执行提案失败:", error);
                alert(`执行提案失败: ${error.message}`);
            }
        }
        
        // 取消投票
        async function cancelVoting() {
            try {
                await contract.methods.cancelVoting().send({ from: accounts[0], gas: 300000 });
                alert("投票已取消");
                await loadContractData();
            } catch (error) {
                console.error("取消投票失败:", error);
                alert(`取消投票失败: ${error.message}`);
            }
        }
    </script>
</body>
</html>